package music.player

import javax.sound.sampled.AudioSystem
import javax.sound.sampled.AudioFormat
import javax.sound.sampled.AudioInputStream
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
import javax.sound.sampled.UnsupportedAudioFileException
import java.io.IOException
import java.lang.Exception
import java.io.File
import java.io.FileInputStream
import java.io.InputStream
import java.io.BufferedInputStream
import music.Formats


object AudioConverter {
  
  // Input sourceBytes, outputFormat audioFormat
  def getAudioDataBytes(source:InputStream, audioFormat:AudioFormat):Array[Byte] = {
    
    
  //throws UnsupportedAudioFileException, IllegalArgumentException, Exception{
        /*if(sourceBytes == null || sourceBytes.length == 0 || audioFormat == null){
            throw new IllegalArgumentException("Illegal Argument passed to this method");
        }*/

        //var bais:ByteArrayInputStream = null;
        var baos:ByteArrayOutputStream = null;
        var sourceAIS:AudioInputStream = null;
        var convert1AIS:AudioInputStream = null;
        var convert2AIS:AudioInputStream = null;

        try{
            //bais = new ByteArrayInputStream(source);
            sourceAIS = AudioSystem.getAudioInputStream(source);
            val sourceFormat:AudioFormat = sourceAIS.getFormat();
            val convertFormat:AudioFormat = new AudioFormat(
                AudioFormat.Encoding.PCM_SIGNED, 
                sourceFormat.getSampleRate(), 
                16, 
                sourceFormat.getChannels(), 
                sourceFormat.getChannels()*2, 
                sourceFormat.getSampleRate(), 
                false
            );
            convert1AIS = AudioSystem.getAudioInputStream(convertFormat, sourceAIS);
            convert2AIS = AudioSystem.getAudioInputStream(audioFormat, convert1AIS);

            
            baos = new ByteArrayOutputStream();

            val buffer:Array[Byte] = new Array[Byte](8192);
            
            // TODO(5) clean this up?
            var readCount:Int = 0;
            while(readCount > -1){
              readCount = convert2AIS.read(buffer, 0, buffer.length);
              if(readCount > -1){
                baos.write(buffer, 0, readCount);
              }
            }
            
            return baos.toByteArray();
            
            
        } catch {
          case uafe:UnsupportedAudioFileException  =>
            //uafe.printStackTrace();
            throw uafe;
          case ioe:IOException => 
            //ioe.printStackTrace();
            throw ioe;
          case iae:IllegalArgumentException =>
            //iae.printStackTrace();
            throw iae;
          case e:Exception =>
            //e.printStackTrace();
            throw e;
        } finally {
          if(baos != null){ try{ 		baos.close(); } catch { case e:Exception => ;} }
          if(convert2AIS != null){ try{ convert2AIS.close(); } catch { case e:Exception => ;} }
          if(convert1AIS != null){ try{ convert1AIS.close(); } catch { case e:Exception => ;} }
          if(sourceAIS != null){ try{ 	sourceAIS.close(); } catch { case e:Exception => ;} }
          //if(bais != null){ try{ 		bais.close(); } catch { case e:Exception => ; } }
        }
    }
  
}